package com.sky.business.sys.handler.cmcc;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.sky.business.sys.domain.CameraConfig;
import com.sky.business.sys.domain.Group;
import com.sky.business.sys.domain.SystemConfig;
import com.sky.business.sys.dto.CameraRtspInfo;
import com.sky.business.sys.dto.OnvifDeviceInfo;
import com.sky.business.sys.event.CmccCreateDeviceEvent;
import com.sky.business.sys.event.CmccCreateDeviceReportEvent;
import com.sky.business.sys.event.DeviceInfo;
import com.sky.business.sys.handler.MqttEventHandler;
import com.sky.business.sys.service.*;
import com.sky.business.sys.util.MQTTClientUtils;
import com.sky.common.config.CacheConstants;
import com.sky.common.utils.GeneratorUtil;
import com.sky.common.utils.NumberUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.SimpleTimeZone;

/**
 * 创建设备事件处理器
 *
 */
@Slf4j
@Component
public class CreateDeviceEventHandler implements MqttEventHandler {

    public static ObjectMapper objectMapper = new ObjectMapper().setTimeZone(SimpleTimeZone.getTimeZone("GMT+8"));

    @Autowired
    private SystemConfigService systemConfigService;

    @Autowired
    private CameraConfigService cameraConfigService;

    @Autowired
    private GroupService groupService;

    @Autowired
    private OnvifService onvifService;

    @Autowired
    private TaskService taskService;

    @Override
    public boolean match(String topic, String msg,String event) {
        return "CreateDevice".equals(event);
    }

    /**
     * 构建设备id
     *
     * @param systemConfig 系统配置
     * @return 设备id
     */
    public String buildDeviceId(SystemConfig systemConfig) {
        String deviceId;
        CameraConfig other;
        do {
            deviceId = GeneratorUtil.generateDeviceId(systemConfig.getEdgeId());
            other = cameraConfigService.findByDeviceId(deviceId);
        } while (other != null);
        return deviceId;
    }



    @Override
    public void handle(String topic, String msg) throws Exception {
        SystemConfig systemConfig = systemConfigService.getSystemConfig();
        CmccCreateDeviceEvent cmccCreateDeviceEvent = objectMapper.readValue(msg, CmccCreateDeviceEvent.class);
        DeviceInfo createDeviceInfo = cmccCreateDeviceEvent.getMetadata().getDeviceInfo();
        CameraConfig exitCameraConfig = cameraConfigService.findByIpAddrAndPort(createDeviceInfo.getDeviceIP(),createDeviceInfo.getOnvifHttpPort());
        String responseMsg;
        if(exitCameraConfig!=null){
            log.error("设备已存在,deviceID:{}",exitCameraConfig.getCameraDeviceId());
            DeviceInfo deviceInfo = cmccCreateDeviceEvent.getMetadata().getDeviceInfo();
            deviceInfo.setOnvifUsername(null);
            deviceInfo.setOnvifPassword(null);
            CmccCreateDeviceReportEvent cmccCreateDeviceReportEvent = new CmccCreateDeviceReportEvent(cmccCreateDeviceEvent.getEdgeId(),"", CacheConstants.CODE_STATUS_ERROR, "设备已存在",  deviceInfo);
            responseMsg = objectMapper.writeValueAsString(cmccCreateDeviceReportEvent);
            //发送消息
            MQTTClientUtils.publish(MQTTClientUtils.CMCC_MQTT_CLIENT, systemConfig.getCmccReportingTopic(), CacheConstants.DEFAULT_QOS, responseMsg);
            return;
        }
        CameraConfig cameraConfig = createDeviceInfo.toCameraConfig();
        List<Group> groupList = groupService.list();
        Group group = groupList.get(0);
        String deviceId = buildDeviceId(systemConfig);
        String dispatcherTopicName = CacheConstants.DISPATCHER_TOPIC_PREFIX+deviceId;
        String pullStreamUrl = "";
        try {
            List<CameraRtspInfo> cameraRtspInfoList = onvifService.getRtspStreamList(cameraConfig.getCameraIp(), NumberUtil.parseInt(cameraConfig.getCameraPort()), cameraConfig.getOnvifUser(), cameraConfig.getOnvifPasswd());
            pullStreamUrl = onvifService.getFhdRtspUrl(cameraRtspInfoList);
            cameraConfig.setPubStreamEnabled(true);
        }catch (Exception e){
            log.error("获取rtsp拉流地址发生异常",e);
            cameraConfig.setPubStreamEnabled(false);
        }

        //获取设备信息
        try {
            OnvifDeviceInfo onvifDeviceInfo = onvifService.getDeviceInformation(cameraConfig.getCameraIp(), NumberUtil.parseInt(cameraConfig.getCameraPort()), cameraConfig.getOnvifUser(), cameraConfig.getOnvifPasswd());
            cameraConfig.setManufacturer(onvifDeviceInfo.getManufacturer());
            cameraConfig.setModel(onvifDeviceInfo.getModel());
            cameraConfig.setFirmwareVersion(onvifDeviceInfo.getFirmwareVersion());
            cameraConfig.setSerialNumber(onvifDeviceInfo.getSerialNumber());
        }catch (Exception e){
            log.info("获取设备制造商、型号等数据时发生异常",e);
        }
        //入库
        cameraConfig.setCameraDeviceId(deviceId);
        cameraConfig.setDispatcherTopic(dispatcherTopicName);
        cameraConfig.setGroupId(group.getId());
        cameraConfig.setPullStream(pullStreamUrl);
        cameraConfig.setAiPullStream(pullStreamUrl);
        cameraConfigService.save(cameraConfig);

        //返回消息
        DeviceInfo deviceInfo = DeviceInfo.valueOf(cameraConfig);
        CmccCreateDeviceReportEvent cmccCreateDeviceReportEvent = new CmccCreateDeviceReportEvent(cmccCreateDeviceEvent.getEdgeId(),deviceId, 200, "",  deviceInfo);
        responseMsg = objectMapper.writeValueAsString(cmccCreateDeviceReportEvent);
        MQTTClientUtils.publish(MQTTClientUtils.CMCC_MQTT_CLIENT, systemConfig.getCmccReportingTopic(), CacheConstants.DEFAULT_QOS, responseMsg);
        //启动转推服务
        if(cameraConfig.getPubStreamEnabled()){
            try {
                taskService.startPubStreamTask(systemConfig, cameraConfig);
            }catch (Exception e){
                log.error("启动转推服务发生异常,设备ID:{}",cameraConfig.getCameraDeviceId(),e);
            }
        }
        //启动追踪服务
        if(!cameraConfig.getSmart() && cameraConfig.getAutoStart()){
            try {
                taskService.startTrackTask(systemConfig, cameraConfig);
            }catch (Exception e){
                log.error("启动追踪服务发生异常,设备ID:{}",cameraConfig.getCameraDeviceId(),e);
            }
        }
    }
}
